/*
 * EchoServer.java
 *
 * Created on September 15, 2007, 9:41 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.lamar.cs.frontgammon.simplechat.server;

// This file contains material supporting section 3.7 of the textbook:
// "Object Oriented Software Engineering" and is issued under the open-source
// license found at www.lloseng.com

import java.io.*;
import com.lloseng.ocsf.server.*;
import edu.lamar.cs.frontgammon.simplechat.server.ServerConsole;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class overrides some of the methods in the abstract
 * superclass in order to give more functionality to the server.
 *
 * @author Dr Timothy C. Lethbridge
 * @author Dr Robert Lagani&egrave;re
 * @author Fran&ccedil;ois B&eacute;langer
 * @author Paul Holden
 * @version July 2000
 */
public class EchoServer extends AbstractServer {
    //Class variables *************************************************
    
    /**
     * The default port to listen on.
     */
    final public static int DEFAULT_PORT = 5555;
    final public static Pattern LOGIN = Pattern.compile ("^\\#login\\s([A-Za-z]+)\\s*");
    
    //Constructors ****************************************************
    
    /**
     * Constructs an instance of the echo server.
     *
     * @param port The port number to connect on.
     */
    public EchoServer(int port) {
        super(port);
    }
    
    
    //Instance methods ************************************************
    
    /**
     * This method handles any messages received from the client.
     *
     * @param msg The message received from the client.
     * @param client The connection from which the message originated.
     */
    //E51 LoginID
    public void handleMessageFromClient(Object msg, ConnectionToClient client){
        
        
        if (msg.toString ().startsWith ("#"))
        {
            Matcher m = null;
            
            if ((m = LOGIN.matcher (msg.toString ())).matches ())
            {
                client.setInfo ("LoginID", m.group (1));
            }
            else
            {
                try
                {
                    client.sendToClient ("Server MSG> Command to server is not recognized.\n");
                    
                    Object o = client.getInfo ("LoginID");
            
                    if (null == o)
                    {
                        try
                        {
                            client.sendToClient ("Server MSG> You must send a LoginID command as your first communication");
                            client.close ();
                        } 
                        catch (IOException ex)
                        {

                        }
                    }
                }
                catch (Exception e)
                {}
            }
            
        }
        else
        {
            Object o = client.getInfo ("LoginID");
            
            if (null != o)
            {
                System.out.println(client.getInfo ("LoginID") + ": " + msg);
                this.sendToAllClients(client.getInfo ("LoginID") + ": " + msg);
            }
            else
            {
                try
                {
                    client.sendToClient ("Server MSG> You must send a LoginID command as your first communication");
                    client.close ();
                } 
                catch (IOException ex)
                {
                    
                }
            }
        }
    }
    
    /**
     * This method overrides the one in the superclass.  Called
     * when the server starts listening for connections.
     */
    protected void serverStarted() {
        System.out.println("Server listening for connections on port " + getPort());
    }
    
    /**
     * This method overrides the one in the superclass.  Called
     * when the server stops listening for connections.
     */
    protected void serverStopped() {
        System.out.println("Server has stopped listening for connections.");
    }
    
    // E49 - Print message for client connects and disconnects
    synchronized protected void clientConnected(ConnectionToClient client) {
        System.out.println("Client connected: " + client.getInetAddress().getHostAddress());
    }
    
    // This currently does not fire due to horrible framework bugs.
    synchronized protected void clientDisconnected(ConnectionToClient client) {
        System.out.println("Client disconnected: " + client.getInetAddress().getHostAddress());
    }
    
    //Class methods ***************************************************
    
    /**
     * This method is responsible for the creation of
     * the server instance (there is no UI in this phase).
     *
     * @param args[0] The port number to listen on.  Defaults to 5555
     *          if no argument is entered.
     */
    public static void main(String[] args) {
        
        int port = 0; //Port to listen on
        
        try {
            port = Integer.parseInt(args[0]); //Get port from command line
        } catch(Throwable t) {
            port = DEFAULT_PORT; //Set port to 5555
        }
        
        EchoServer sv = new EchoServer(port);
        ServerConsole sc = new ServerConsole(sv);
        Thread scThread = new Thread(sc);
        
        try {
            sv.listen(); //Start listening for connections
            scThread.start();
        } catch (Exception ex) {
            System.out.println("ERROR - Could not listen for clients!");
        }
    }
}
//End of EchoServer class
